package cn.com.nes.site.action.iot;

import cn.com.nes.common.em.platform.OpeMethodEnum;
import cn.com.nes.common.util.DBUtils;
import cn.com.nes.common.util.ParameterUtil;
import cn.com.nes.site.entity.DataReq;
import cn.com.nes.site.entity.DataRes;
import cn.com.nes.site.entity.PageData;
import cn.com.nes.site.entity.iot.RegisterDataItemExcel;
import cn.com.nes.site.listener.ProtocolEnumWriteHandler;
import cn.com.nes.site.listener.RegisterDataItemListener;
import cn.com.nes.site.module.service.iot.ProtocolService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller("protocol")
@RequestMapping("/protocol")
public class ProtocolAction {

    @Resource
    private ProtocolService protocolService;

    @RequestMapping("/saveProtocol")
    @ResponseBody
    public PageData saveProtocol(HttpServletRequest request, HttpServletResponse response) {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.saveProtocol(req);
        return res;
    }

    @RequestMapping("/getProtocol")
    @ResponseBody
    public PageData getProtocol(HttpServletRequest request, HttpServletResponse response) {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.getProtocol(req);
        return res;
    }

    @RequestMapping("/deleteProtocol")
    @ResponseBody
    public PageData deleteProtocol(HttpServletRequest request, HttpServletResponse response) {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.deleteProtocol(req);
        return res;
    }

    @RequestMapping("/saveQueryCommand")
    @ResponseBody
    public PageData saveQueryCommand(HttpServletRequest request, HttpServletResponse response) {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.saveQueryCommand(req);
        return res;
    }

    @RequestMapping("/generateModbusCommand")
    @ResponseBody
    public PageData generateModBusCommand(HttpServletRequest request, HttpServletResponse response) {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.generateModBusCommand(req);
        return res;
    }

    @RequestMapping("/getQueryCommands")
    @ResponseBody
    public PageData getQueryCommands(HttpServletRequest request, HttpServletResponse response) {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.getQueryCommands(req);
        return res;
    }

    @RequestMapping("/getDataItemsByQueryCommand")
    @ResponseBody
    public PageData getDataItemsByQueryCommand(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.getDataItemsByQueryCommand(req);
        return res;
    }

    @RequestMapping("/parseData")
    @ResponseBody
    public PageData parseData(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        try {
            res = protocolService.parseData(req);
        } catch (Exception e) {
            return PageData.error("解析失败");
        }
        return res;
    }

    @RequestMapping("/saveProtocolDataItems")
    @ResponseBody
    public PageData saveRegisterDataItems(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        try {
            res = protocolService.saveRegisterDataItems(req);
        } catch (Exception e) {
            e.printStackTrace();
            return PageData.error("保存失败");
        }
        return res;
    }

    @RequestMapping("/getDataItems")
    @ResponseBody
    public PageData getDataItems(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.getDataItems(req);
        return res;
    }

    @RequestMapping("/importProtocol")
    @ResponseBody
    public PageData importProtocol(@RequestParam("file") MultipartFile file, HttpServletRequest request,
                                   HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();
        try {
            String username = req.getUinfo().getUsername();
            String protocolId = ParameterUtil.getString(req, "protocolId");
            String manufactureId = protocolService.getProtocolManufactureId(protocolId, req);
            final RegisterDataItemListener readListener = new RegisterDataItemListener(protocolService, protocolId, manufactureId, username);
            EasyExcel.read(file.getInputStream(), RegisterDataItemExcel.class, readListener).sheet(0).doRead();
            return readListener.getRes();
        }catch (Exception e){
            // add by zhouy
            e.printStackTrace();
            return PageData.error("导入错误");
        }

    }

    @RequestMapping("/exportProtocol")
    @ResponseBody
    public void exportProtocol(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.getDataItems(req);
        List<RegisterDataItemExcel> list = new ArrayList<>();
        String fileName;
        if (CollUtil.isNotEmpty(res.getPage())) {
            for (Map<String, Object> o : res.getPage()) {
                RegisterDataItemExcel registerDataItemExcel =
                        BeanUtil.mapToBean(o, RegisterDataItemExcel.class, true);

                // add by zhouy
                // ----------------------------------------------------
                boolean readable =(Boolean) o.get("readable");
                boolean writable = (Boolean)o.get("writable");
                registerDataItemExcel.setExcelReadWriteType(readable, writable);
                // ----------------------------------------------------

                list.add(registerDataItemExcel);
            }
            final PageData protocol = protocolService.getProtocol(req);
            fileName = (String) protocol.getPage().get(0).get("name");
        } else {
            // 模板文件
            for (int i = 0; i < 500; i++) {
                list.add(new RegisterDataItemExcel());
            }
            fileName = "模板";
        }
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
        EasyExcel.write(response.getOutputStream(), RegisterDataItemExcel.class)
                .registerWriteHandler(new ProtocolEnumWriteHandler(list.size()))
                .sheet().doWrite(list);
    }

    @RequestMapping("/deleteDataItem")
    @ResponseBody
    public PageData deleteDataItem(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.deleteDataItem(req);
        return res;
    }

    @RequestMapping("/getProtocolQueryCommand")
    @ResponseBody
    public PageData getProtocolQueryCommand(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.getProtocolQueryCommand(req);
        return res;
    }

    @RequestMapping("getControlCommands")
    @ResponseBody
    public PageData getRequestControlCommand(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.getControlCommands(req);
        return res;
    }

    @RequestMapping("sendCommand")
    @ResponseBody
    public JSONObject sendControlCommand(HttpServletRequest request, HttpServletResponse response) {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, false);
        DataReq req = req_Status.getReq();
        String url = OpeMethodEnum.sendCommand.url();
        String json = JSON.toJSONString(req.getReqData());
        return JSONObject.parseObject(HttpUtil.post(url, json));
    }

    @RequestMapping("saveStandardDataItem")
    @ResponseBody
    public PageData saveStandardDataItem(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.saveStandardDataItem(req);
        return res;
    }

    @RequestMapping("getStandardDataItems")
    @ResponseBody
    public PageData getStandardDataItems(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.getStandardDataItems(req);
        return res;
    }

    /**
     * 获取协议数据项下拉框-配置标准项
     *
     * @param request  HttpServletRequest
     * @param response HttpServletResponse
     * @return PageData
     * @throws Exception Exception
     */
    @RequestMapping("/getDataItemsForDropdown")
    @ResponseBody
    public PageData getDataItemsForDropdown(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.getDataItemsForDropdown(req);
        return res;
    }

    @RequestMapping("/getControlCommandForDropdown")
    @ResponseBody
    public PageData getControlCommandForDropdown(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.getControlCommandForDropdown(req);
        return res;
    }

    @RequestMapping("/getClassify")
    @ResponseBody
    public PageData getClassify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res;
        if (req_Status.getRetCode() != 0) {
            res = new PageData();
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();

        res = protocolService.getClassify(req);
        return res;
    }

    @RequestMapping("/getManufactures")
    public PageData getManufactures(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res = new PageData();
        if (req_Status.getRetCode() != 0) {
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();
        res = protocolService.getManufactures(req);
        return res;
    }

    @RequestMapping("/getProtocolFaultDataItemRelation")
    @ResponseBody
    public PageData getProtocolFaultDataItemRelation(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res = new PageData();
        if (req_Status.getRetCode() != 0) {
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();
        res = protocolService.getProtocolFaultDataItemRelation(req);
        return res;
    }

    @RequestMapping("/saveProtocolFaultDataItemRelation")
    @ResponseBody
    public PageData saveProtocolFaultDataItemRelation(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res = new PageData();
        if (req_Status.getRetCode() != 0) {
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();
        res = protocolService.saveProtocolFaultDataItemRelation(req);
        return res;
    }

    @RequestMapping("/deleteProtocolFaultDataItemRelation")
    @ResponseBody
    public PageData deleteProtocolFaultDataItemRelation(HttpServletRequest request, HttpServletResponse response) throws Exception {
        DataRes req_Status = DBUtils.setRemoteVisit(request, response, true);
        PageData res = new PageData();
        if (req_Status.getRetCode() != 0) {
            res.setRetCode(req_Status.getRetCode());
            res.setRetMessage(req_Status.getRetMessage());
            return res;
        }
        DataReq req = req_Status.getReq();
        res = protocolService.deleteProtocolFaultDataItemRelation(req);
        return res;
    }

}
